<?php

namespace App\Http\Controllers;


use http\Env\Response;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use App\Models\Home\Website as WebModel;
use App\Models\Home\Posts as PostsModel;
use App\Models\User\User as UserModel;
use App\Models\Home\Contact as ContactModel;
use App\Models\Home\Comments as CommentsModel;
use App\Models\Home\Food as FoodModel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactVerificationMail;
use Illuminate\Pagination\LengthAwarePaginator;

class HomeController extends Controller
{
  // 主页
  public function index(Request $request)
  {
    // 使用 PostModel 查询数据库中的所有状态为‘发布’的文章，并按照创建时间倒序排序
    // $postsIndex = PostsModel::orderBy('created_at', 'desc')->get();
    // 使用 with 方法预加载作者信息 2024。3.12
    // Redis 不支持分页对象的序列化,所以不缓存分页数据 而是缓存数据库查询的原始数据 toArray()，然后在取出时重新分页

    $cacheKey = 'home_index'; // 哈希键，是顶级域名，通过与相关字段组织在一起
    $postsCount = Redis::hget($cacheKey, 'postsCount'); // 哈希键下面的字段，通过字段名，可以从哈希键中获取特定数据
    $postsData = Redis::hget($cacheKey, 'postsData');
    if (!$postsCount || !$postsData) {
      $postsCount = PostsModel::where('status', 'PUBLISHED')->count();

      $posts = PostsModel::with('author')->where('status', 'PUBLISHED')->orderBy('created_at', 'desc')->get()->toArray();
      // 存储到Redis哈希中
      Redis::hset($cacheKey, 'postsCount', $postsCount);
      Redis::hset($cacheKey, 'postsData', json_encode($posts));
      Redis::expire($cacheKey, 3600); // 过期时间1小时
    } else {
      $posts = json_decode($postsData, true); // 解析为关联数组，$data['id'] 可以直接访问
      // 不加true返回的是stdClass要用$data->'id'访问
    }
    $posts = collect($posts);
    // ***分页处理***
    $currentPage = LengthAwarePaginator::resolveCurrentPage();
    $perPage = 8; // 每页8条
    $currentItems = $posts->slice(($currentPage - 1) * $perPage, $perPage)->values();

    // 重新创建分页对象
    $postsIndex = new LengthAwarePaginator(
      $currentItems,
      count($posts),
      $perPage,
      $currentPage,
      ['path' => $request->url(), 'query' => $request->query()]
    );

    $data = compact([
      'postsIndex',
      'postsCount'
    ]);
    // 将数据传递给视图
    return view('index', $data);
  }


  // 留言界面
  public function contact()
  {
    // 留言总数
    $count = ContactModel::count();
    // 查询每个留言的内容，用于展示
    $message = ContactModel::orderBy('created_at', 'desc')->paginate(3); // 每页显示3条留言
    $data = compact([
      'count',
      'message'
    ]);
    return view('contact', $data);
  }


  // 处理留言提交
  public
  function contact_form(Request $request)
  {
    $message = [
      'email.required' => '邮箱是必填项。',
      'email.email' => '请输入有效的邮箱地址。',
      'verification_code.required' => '验证码是必填项。',
      'verification_code.numeric' => '验证码必须是数字。',
      'name.required' => '姓名是必填项。',
      'name.string' => '姓名必须是字符串。',
      'content.required' => '留言内容是必填项。',
      'content.string' => '留言内容必须是字符串。',
    ];
    // 验证器直接生效，并且可以自定义错误信息
    $request->validate([
      'email' => 'required|email',
      'verification_code' => 'required|numeric',
      'name' => 'required|string',
      'content' => 'required|string',
    ], $message);


    // 获取提交的内容
    $email = $request->input('email');
    $verificationCode = $request->input('verification_code');
    $name = $request->input('name');
    $content = $request->input('content');
    // 有人恶意提交留言，做广告，设置同一ip内短时间不能留言
    $ip = request()->ip();

    // 从缓存中获取验证码
    $cachedCode = Cache::get('verification_code_' . $email);

    if (!$cachedCode || $cachedCode != $verificationCode) {
      return response()->json(['error' => '验证码错误或已过期，请重新获取验证码。'], 400);
    }
    // 清除验证码缓存
    Cache::forget('verification_code_' . $email);


    // 转成json格式
    $ipAddress = json_encode($ip);
    // 获取上次提交留言的时间
    $lastSubmitTime = Cache::get('last_submit_time_' . $ip);

    //now()->diffInMinutes($lastSubmitTime) 计算当前时间与上次留言提交时间的时间差（单位为分钟）
    // 检查用户是否在短时间内多次留言
    $lastSubmitTime = Cache::get('last_submit_time_' . $ip);
    echo $ip;
    if ($lastSubmitTime && now()->diffInMinutes($lastSubmitTime) < 1) {
      // return redirect('/contact')->with('error', '留言失败，短时间内禁止重复提交！');
      return response()->json(['error' => '留言失败，短时间内禁止重复提交！'], 400);
    }
    // 创建留言内容
    $params = [
      'name' => $name,
      'email' => $email,
      'content' => $content,
      'ip' => json_encode($ip),
    ];
    // dd($lastSubmitTime);
    $result = ContactModel::create($params);

    if ($result) {
      // 更新缓存中的留言时间 // 设置有效期为 1 分钟
      Cache::put('last_submit_time_' . $ip, now(), now()->addMinutes(1));

      // 留言成功
      // return redirect('/contact')->with('success', '留言成功！');
      return response()->json(['success' => '留言成功！'], 200);
    } else {
      // 留言失败
      // return redirect('')->with('error', '留言失败！');
      return response()->json(['error' => '留言失败'], 400);
    }
  }


  // 发送验证码
  public function sendVerificationCode(Request $request)
  {
    $request->validate([
      'email' => 'required|email',
    ]);

    $email = $request->input('email');

    // 检查短时间内是否重复发送
    $lastSendTime = Cache::get('last_send_time_' . $email);
    if ($lastSendTime && now()->diffInSeconds($lastSendTime) < 60) {
      return response()->json(['message' => '验证码发送过于频繁，请稍后重试。'], 429);
    }

    // 生成随机6位数字验证码
    $verificationCode = random_int(100000, 999999);

    // 设置五分钟缓存
    Cache::put('verification_code_' . $email, $verificationCode, now()->addMinutes(5));

    // 发送验证码
    Mail::to($email)->send(new ContactVerificationMail($verificationCode));

    Cache::put('last_send_time_' . $email, now());
    return response()->json(['message' => '验证码已发送到您的邮箱，请查收。']);
  }

  public function contact_like($contactId)
  {
    // 执行点赞逻辑，这里你需要更新数据库中的点赞数
    $contact = ContactModel::find($contactId);

    if (!$contact) {
      return response()->json(['error' => '该留言不存在'], 404);
    }

    // 获取客户点IP地址
    $ClientIP = request()->ip();

    $CacheKey = 'like_' . $contactId . '_' . $ClientIP;
    if (Cache::has($CacheKey)) {
      return response()->json(['error' => '您已经点赞过！'], 400);
    }

    // 获取字段值并+1
    $likecount = $contact->like + 1;

    // 更新字段值
    $contact->like = $likecount;

    $contact->save();

    // 将点赞记录写入 Cache，设置过期时间，例如10分钟
    Cache::put($CacheKey, true, now()->addMinutes(999));
    // 返回新的点赞数
    return response()->json(['LikeCount' => $likecount]);
  }


  public
  function website()
  {
    // 使用 WebModel 模型查询网站类型为1的所有数据
    $websites1 = WebModel::where('category', 1)->get();

    // 使用 WebModel 模型查询网站类型为1的所有数据
    $websites2 = WebModel::where('category', 2)->get();

    $websites3 = WebModel::where('category', 3)->get();

    $data = compact([
      'websites1',
      'websites2',
      'websites3'
    ]);

    // 将查询结果传递给视图
    return view('website', $data);
  }


  // 文章详情页面
  public
  function posts($id)
  {
    // 根据文章ID加载文章内容
    $posts = PostsModel::find($id);

    // 查询这篇文章的作者id
    $Authorid = $posts->author_id;

    // dd($Authorid);

    // 查询作者信息
    $AuthorInfo = UserModel::find($Authorid);

    // 查询这篇文章的评论
    $comment = CommentsModel::where('post_id', $id)->get();

    // 返回到文章详情页面，并传递文章信息
    $data = compact([
      'posts',
      'AuthorInfo',
      'comment'
    ]);
    // dd($AuthorInfo);

    // 将查询结果传递给视图
    return view('posts', $data);
  }

  // 文章内容点赞请求
  public function like_request($post_id)
  {
    // 根据文章ID加载文章内容
    $posts = PostsModel::find($post_id);

    if (!$posts) {
      return response()->json(['error' => '该文章不存在！'], 404);
    }

    // 获取客户点IP地址
    $clientIP = request()->ip();

    // 使用缓存检查是否已经点赞过,设置唯一缓存值
    $cacheKey = 'like_' . $post_id . '_' . $clientIP;
    if (Cache::has($cacheKey)) {
      return response()->json(['error' => '您已经点赞过！'], 400);
    }

    // 获取文章的"like"字段的值
    $newLikeCount = $posts->like + 1;

    // 更新模型的like字段
    $posts->like = $newLikeCount;

    // 保存更新后的值
    $posts->save();

    // 将点赞记录写入 Cache，设置过期时间，例如10分钟
    Cache::put($cacheKey, true, now()->addMinutes(999));


    // 返回新的点赞数
    // response() 函数是 Laravel 中用于创建响应实例的全局辅助函数。
    return response()->json(['newLikeCount' => $newLikeCount]);
  }


  // 文章浏览量+1
  public function increaseViewCount($PostId)
  {
    $posts = PostsModel::find($PostId);

    $userIp = request()->ip();
    if (!$posts) {
      return response()->json(['error' => '该文章不存在！'], 404);
    }

    // json_decode 解码JSON格式的数据为数组
    $viewedIps = json_decode($posts->viewed_ips, true) ?? [];

    // json_decode 解码JSON格式的数据
    if ($posts && !in_array($userIp, $viewedIps)) {
      // 如果未浏览过，浏览量加1
      $NewViewCount = $posts->view + 1;

      // 记录用户的ip，避免重复增加
      $viewedIps[] = $userIp; // 将用户ip地址添加到数组中
      $posts->viewed_ips = json_encode($viewedIps); // 保存到数据库

      $posts->view = $NewViewCount; // 更新浏览次数字段
      $posts->save();

      return response()->json(['success' => true, 'NewViewCount' => $NewViewCount]);
    } else {
      return response()->json(['success' => false, 'message' => '该用户已经浏览过该文章']);
    }
  }

  // 文章发表评论
  public function PostComment(Request $request, $PostID)
  {
    // 检查用户是否已登录  先查 先查 先查
    $LoginUser = !empty($request->cookie('LoginUser')) ? json_decode($request->cookie('LoginUser'), true) : [];
    //  获取用户评论的内容
    $commentText = $request->input('comment');
    // dd($params);
    if (empty($LoginUser)) {
      // dd('用户未登录，将执行重定向');
      return response()->json(['error' => '请先登录！'], 400);
    }
    // 用户名
    $Username = !empty($LoginUser['name']) ? $LoginUser['name'] : 0;
    // 用户头像 使用的时候前面要加 uploads/
    $UserAvatar = !empty($LoginUser['avatar']) ? $LoginUser['avatar'] : '';

    $UserId = !empty($LoginUser['id']) ? $LoginUser['id'] : 0;
    // dd($LoginUser);

    // 创建新的评论记录
    $comment = new CommentsModel();
    $comment->post_id = check_input($PostID);
    $comment->userid = check_input($UserId);
    $comment->username = check_input($Username);
    $comment->avatar = check_input($UserAvatar);
    $comment->content = check_input($commentText);
    $result = $comment->save();

    if ($result === false) {
      return response()->json(['error' => '评论失败!'], 400);
    } else {
      return response()->json(['success' => '评论成功!'], 200);
    }
  }

  // 加载更多评论
  public function loadMore($PostID)
  {
    $commentCount = CommentsModel::where('post_id', $PostID)->count();
    //查询全部评论,跳过前五条数据，从第六条获取
    $comment = CommentsModel::where('post_id', $PostID)->limit($commentCount)->offset(5)->get();

    return response()->json(['comment' => $comment], 200);
  }

  //食物页面
  public function food()
  {
    $vegetables = FoodModel::where('category', 1)->pluck('food_name');
    $meats = FoodModel::where('category', 2)->pluck('food_name');
    $stapleFood = FoodModel::where('category', 3)->pluck('food_name');
    $menus = FoodModel::where('category', 4)->pluck('food_name');

    $data = compact([
      'vegetables',
      'meats',
      'stapleFood',
      'menus'
    ]);
    return view('food', $data);
  }
}
